﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using PivotServerTools;

namespace CollectionFactories.TeamCity
{
    internal class TeamCityBuildsCollectionFactory : TeamCityCollectionFactoryBase
    {
        public override bool CanHandle(CollectionRequestContext context)
        {
            return context.Query["type"] == "builds";
        }

        protected override Collection Handle(CollectionRequestContext context, string responseString)
        {
            if (string.IsNullOrEmpty(context.Query["buildTypeId"]))
                return ErrorCollection.FromException(new ArgumentException("If you want to see builds you need to supply a build type id"));

            XDocument document;

            try
            {
                document = XDocument.Parse(responseString);
            }
            catch (Exception e)
            {
                return ErrorCollection.FromException(e);
            }

            var builds = from b in document.Descendants("build")
                         select new
                                    {
                                        Number = b.Attribute("number").Value,
                                        Id = b.Attribute("id").Value,
                                        Status = b.Attribute("status").Value,
                                        RestUri = MakeRestUri(b.Attribute("href").Value)
                                    };

            var buildsWithDetails = from b in builds
                                    let details = XDocument.Parse(GetResponseString(string.Format("/app/rest/builds/id:{0}", b.Id))).Element("build")
                                    select new
                                               {
                                                   b.Number,
                                                   b.Id,
                                                   b.RestUri,
                                                   b.Status,
                                                   Url = MakeUserUri(details.Attribute("webUrl").Value),
                                                   Personal = details.Attribute("personal").Value,
                                                   History = details.Attribute("history").Value,
                                                   Pinned = details.Attribute("pinned").Value,
                                                   StartDate = ParseDate(details.Element("startDate").Value),
                                                   FinishDate = ParseDate(details.Element("finishDate").Value),
                                                   Agent = details.Element("agent").Attribute("name").Value
                                               };

            var collection = new Collection { Name = "TeamCity builds" };

            foreach (var build in buildsWithDetails)
            {
                collection.AddItem(build.Number, build.Url, build.Number + " " + build.Status + " Start: " + build.StartDate + " Finish: " + build.FinishDate, null,
                                   new Facet("Personal", FacetType.Text, build.Personal), 
                                   new Facet("History", FacetType.Text, build.History), 
                                   new Facet("Pinned", FacetType.Text, build.Pinned),
                                   new Facet("Status", FacetType.Text, build.Status),
                                   new Facet("Agent", FacetType.Text, build.Agent)
                    );
            }

            return collection;
        }

        private static DateTime ParseDate(string value)
        {
            return DateTime.ParseExact(value, "yyyyMMddTHHmmsszzzz", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
        }

        protected override string Resource(CollectionRequestContext context)
        {
            return string.Format("/app/rest/buildTypes/id:{0}/builds/", context.Query["buildTypeId"]);
        }

        protected override IEnumerable<KeyValuePair<string, string>> AddCollectionUrlQueryString(string value)
        {
            yield return new KeyValuePair<string, string>("type", "builds");
            yield return new KeyValuePair<string, string>("buildTypeId", value);
        }
    }
}